﻿using System;
using System.Data;
using System.Data.Common;
using Campeonato.Model;
using Microsoft.Practices.EnterpriseLibrary.Data;
using log4net;
using Campeonato.Common.Extensions;
using System.Collections.Generic;

namespace Campeonato.Common.DAL
{
    class JogadorVirtualDAL
    {
        private static ILog s_logger;
        private static ILog Logger
        {
            get
            {
                if (s_logger == null)
                {
                    s_logger = LogManager.GetLogger("JogadorVirtualDAL");
                }

                return s_logger;
            }
        }

        internal JogadorVirtual BuscarJogadorVirtual(long _jogadorID, string _nomeJogadorVirtual)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols
                            FROM
                                 Jogador_Virtual JV,
                                 Jogador_Jog_Virtual JJV
                            WHERE
                                 JV.jog_virtual_id = JJV.jog_virtual_id AND
                                 JJV.jogador_id = {0} AND
                                 JV.nome_jogador = {1}";
            
            JogadorVirtual j = null;

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_jogadorID), DbParam.Create(_nomeJogadorVirtual));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                if (dbReader.Read())
                {
                    j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = _jogadorID;
                }
            }

            return j;
        }

        internal JogadorVirtual CriaJogadorVirtual(long _jogadorID, string _nomeJogador)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"INSERT INTO Jogador_Virtual 
                            (nome_jogador, total_cartoes_amarelos, total_cartoes_vermelhos, suspenso, rodada_suspenso, qtde_rodadas_suspenso, total_gols) 
                           VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6})";

            DbCommand cmd = db.CreateCommand(sql, 
                DbParam.Create(_nomeJogador),
                DbParam.Create(0),
                DbParam.Create(0),
                DbParam.Create(false),
                DbParam.Create(0),
                DbParam.Create(0),
                DbParam.Create(0));

            JogadorVirtual j = new JogadorVirtual();
            using (DbConnection connection = db.CreateConnection())
            {
                connection.Open();
                DbTransaction transaction = connection.BeginTransaction();
                try
                {
                    db.ExecuteNonQuery(cmd, transaction);
                    j.ID = db.GetIdentityValue(transaction, "");
                    j.Nome = _nomeJogador;
                    sql = "INSERT INTO Jogador_Jog_Virtual (jog_virtual_id, jogador_id) VALUES ({0}, {1})";
                    cmd = db.CreateCommand(sql, DbParam.Create(j.ID), DbParam.Create(_jogadorID));
                    db.ExecuteNonQuery(cmd, transaction);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    Logger.Error("Ocorreu um erro ao criar o registro do jogador virtual.", ex);
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    connection.Close();
                }
            }

            return j;
        }

        internal void AtualizaEstatisticas(JogadorVirtual _jogadorVirtual)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"UPDATE Jogador_Virtual SET
                            total_cartoes_amarelos = {0},
                            total_cartoes_vermelhos = {1},
                            suspenso = {2},
                            rodada_suspenso = {3},
                            qtde_rodadas_suspenso = {4},
                            total_gols = {5}
                           WHERE
                            jog_virtual_id = {6}";

            DbCommand cmd = db.CreateCommand(sql, 
                DbParam.Create(_jogadorVirtual.TotalCartoesAmarelos),
                DbParam.Create(_jogadorVirtual.TotalCartoesVermelhos),
                DbParam.Create(_jogadorVirtual.Suspenso),
                DbParam.Create(_jogadorVirtual.RodadaSuspensao),
                DbParam.Create(_jogadorVirtual.QtdeRodadasSuspenso),
                DbParam.Create(_jogadorVirtual.TotalGolsMarcados),
                DbParam.Create(_jogadorVirtual.ID));

            db.ExecuteNonQuery(cmd);
        }

        internal void InserePartidaJogadorVirtual(PartidaJogadorVirtual _partidaJogVirtual)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"INSERT INTO Partida_Jog_Virtual 
                                        (partida_id, 
                                         jog_virtual_id, 
                                         cartao_amarelo, 
                                         expulso, 
                                         gols_marcados) 
                            VALUES ({0}, {1}, {2}, {3}, {4})";

            DbCommand cmd = db.CreateCommand(sql,
                DbParam.Create(_partidaJogVirtual.PartidaDisputada.ID),
                DbParam.Create(_partidaJogVirtual.JogadorVirtual.ID),
                DbParam.Create(_partidaJogVirtual.CartoesAmarelos),
                DbParam.Create(_partidaJogVirtual.RecebeuCartaoVermelho),
                DbParam.Create(_partidaJogVirtual.QtdeGolsMarcados));

            db.ExecuteNonQuery(cmd);
        }

        internal bool ExisteRegistroPartida(long _partidaID, string _nomeJogadorVirtual)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT COUNT(*) 
                           FROM
                                Partida_Jog_Virtual PJV,
                                Jogador_Virtual JV
                           WHERE
                                JV.jog_virtual_id = PJV.jog_virtual_id AND
                                JV.nome_jogador = {0} AND
                                PJV.partida_id = {1}";

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_nomeJogadorVirtual), DbParam.Create(_partidaID));

            int count = Convert.ToInt32(db.ExecuteScalar(cmd));

            return count > 0;
        }

        internal List<JogadorVirtual> BuscarJogadoresSuspensos(long _jogadorID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols
                            FROM
                                 Jogador_Virtual JV,
                                 Jogador_Jog_Virtual JJV
                            WHERE
                                 JV.jog_virtual_id = JJV.jog_virtual_id AND
                                 JJV.jogador_id = {0} AND
                                 JV.suspenso = {1}";

            List<JogadorVirtual> jogadoresSuspensos = new List<JogadorVirtual>();

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_jogadorID), DbParam.Create(true));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                while (dbReader.Read())
                {
                    JogadorVirtual j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = _jogadorID;

                    jogadoresSuspensos.Add(j);
                }
            }

            return jogadoresSuspensos;
        }

        internal List<JogadorVirtual> BuscarJogadoresVirtuais(long _jogadorID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols
                            FROM
                                 Jogador_Virtual JV,
                                 Jogador_Jog_Virtual JJV
                            WHERE
                                 JV.jog_virtual_id = JJV.jog_virtual_id AND
                                 JJV.jogador_id = {0}
                            ORDER BY JV.nome_jogador";

            List<JogadorVirtual> jogadoresVirtuais = new List<JogadorVirtual>();

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_jogadorID));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                while (dbReader.Read())
                {
                    JogadorVirtual j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = _jogadorID;

                    jogadoresVirtuais.Add(j);
                }
            }

            return jogadoresVirtuais;
        }

        internal List<PartidaJogadorVirtual> BuscarEstatisticasJogVitualPartida(long _partidaID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 PJV.partida_id,                               
                                 PJV.jog_virtual_id,
                                 JV.nome_jogador,
                                 PJV.cartao_amarelo,
                                 PJV.expulso,
                                 PJV.gols_marcados,
                                 J.jogador_id,
                                 J.nome
                            FROM
                                 Jogador_Virtual JV,
                                 Partida_Jog_Virtual PJV,
                                 Jogador_Jog_Virtual JJV,
                                 Jogador J
                            WHERE
                                 JJV.jogador_id = J.jogador_id AND
                                 JJV.jog_virtual_id = JV.jog_virtual_id AND
                                 JV.jog_virtual_id = PJV.jog_virtual_id AND
                                 PJV.partida_id = {0}";

            List<PartidaJogadorVirtual> lstPartidaJogVirtual = new List<PartidaJogadorVirtual>();

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_partidaID));

             using (IDataReader dbReader = db.ExecuteReader(cmd))
             {
                 while (dbReader.Read())
                 {
                     PartidaJogadorVirtual p = new PartidaJogadorVirtual();
                     p.PartidaDisputada = new Partida();
                     p.PartidaDisputada.ID = dbReader.GetValue<long>(0);
                     p.JogadorVirtual = new JogadorVirtual();
                     p.JogadorVirtual.ID = dbReader.GetValue<long>(1);
                     p.JogadorVirtual.Nome = dbReader.GetValue<string>(2);
                     p.JogadorVirtual.Jogador = new Jogador();
                     p.JogadorVirtual.Jogador.ID = dbReader.GetValue<long>(6);
                     p.JogadorVirtual.Jogador.Nome = dbReader.GetValue<string>(7);
                     p.CartoesAmarelos = dbReader.GetValue<int>(3);
                     p.RecebeuCartaoVermelho = dbReader.GetValue<bool>(4);
                     p.QtdeGolsMarcados = dbReader.GetValue<int>(5);

                     lstPartidaJogVirtual.Add(p);
                 }
             }

            return lstPartidaJogVirtual;
        }

        internal void AtualizaPartidaJogadorVirtual(PartidaJogadorVirtual partJogVirt)
        {
            string sql = @"UPDATE Partida_Jog_virtual 
                                    SET cartao_amarelo = {0},
                                    expulso = {1},
                                    gols_marcados = {2}
                            WHERE
                                    partida_id = {3} AND
                                    jog_virtual_id = {4}";

            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(partJogVirt.CartoesAmarelos),
                DbParam.Create(partJogVirt.RecebeuCartaoVermelho),
                DbParam.Create(partJogVirt.QtdeGolsMarcados),
                DbParam.Create(partJogVirt.PartidaDisputada.ID),
                DbParam.Create(partJogVirt.JogadorVirtual.ID));

            db.ExecuteNonQuery(cmd);
        }

        internal JogadorVirtual BuscarJogadorVirtual(long _jogadorVirtualID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols
                            FROM
                                 Jogador_Virtual JV
                            WHERE
                                 JV.jog_virtual_id = {0}";

            JogadorVirtual j = null;

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_jogadorVirtualID));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                if (dbReader.Read())
                {
                    j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = _jogadorVirtualID;
                }
            }

            return j;
        }

        internal List<JogadorVirtual> BuscarJogadoresVirtuaisOrdenadosPorTotalGols(int _campeonatoID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols,
                                 J.jogador_id,
                                 J.nome,
                                 J.time_escolhido
                            FROM
                                 Jogador_Virtual JV,
                                 Jogador_Jog_Virtual JJV,
                                 Campeonato_Jogadores CJ,
                                 Jogador J
                            WHERE
                                 CJ.campeonato_id = {0} AND
                                 CJ.jogador_id = JJV.jogador_id AND
                                 JV.jog_virtual_id = JJV.jog_virtual_id AND
                                 J.jogador_id = CJ.jogador_id AND
                                 JV.total_gols > 0
                            ORDER BY JV.total_gols DESC, J.nome ASC";

            List<JogadorVirtual> jogadores = new List<JogadorVirtual>();

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_campeonatoID));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                while (dbReader.Read())
                {
                    JogadorVirtual j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = dbReader.GetValue<long>(8);
                    j.Jogador.Nome = dbReader.GetValue<string>(9);
                    j.Jogador.TimeEscolhido = dbReader.GetValue<string>(10);

                    jogadores.Add(j);
                }
            }

            return jogadores;
        }

        internal List<JogadorVirtual> BuscarJogadoresVirtuaisOrdenadosPorCartoes(int _campeonatoID)
        {
            Database db = DatabaseFactory.CreateDatabase(DBHelper.PES_DATABASE);

            string sql = @"SELECT 
                                 JV.jog_virtual_id,
                                 JV.nome_jogador,
                                 JV.total_cartoes_amarelos,
                                 JV.total_cartoes_vermelhos,
                                 JV.suspenso,
                                 JV.rodada_suspenso,
                                 JV.qtde_rodadas_suspenso,
                                 JV.total_gols,
                                 J.jogador_id,
                                 J.nome,
                                 J.time_escolhido,
                                 ( ((JV.total_cartoes_amarelos/3) + JV.total_cartoes_vermelhos) ) AS total_susp 
                            FROM
                                 Jogador_Virtual JV,
                                 Jogador_Jog_Virtual JJV,
                                 Campeonato_Jogadores CJ,
                                 Jogador J
                            WHERE
                                 CJ.campeonato_id = {0} AND
                                 CJ.jogador_id = JJV.jogador_id AND
                                 JV.jog_virtual_id = JJV.jog_virtual_id AND
                                 J.jogador_id = CJ.jogador_id AND
                                 (JV.total_cartoes_amarelos > 0 OR JV.total_cartoes_vermelhos > 0)
                            ORDER BY total_susp DESC, JV.total_cartoes_vermelhos DESC, JV.total_cartoes_amarelos DESC, J.nome ASC";

            List<JogadorVirtual> jogadores = new List<JogadorVirtual>();

            DbCommand cmd = db.CreateCommand(sql, DbParam.Create(_campeonatoID));

            using (IDataReader dbReader = db.ExecuteReader(cmd))
            {
                while (dbReader.Read())
                {
                    JogadorVirtual j = new JogadorVirtual();
                    j.ID = dbReader.GetValue<long>(0);
                    j.Nome = dbReader.GetValue<string>(1);
                    j.TotalCartoesAmarelos = dbReader.GetValue<int>(2);
                    j.TotalCartoesVermelhos = dbReader.GetValue<int>(3);
                    j.Suspenso = dbReader.GetValue<bool>(4);
                    j.RodadaSuspensao = dbReader.GetValue<int>(5);
                    j.QtdeRodadasSuspenso = dbReader.GetValue<int>(6);
                    j.TotalGolsMarcados = dbReader.GetValue<int>(7);
                    j.Jogador = new Jogador();
                    j.Jogador.ID = dbReader.GetValue<long>(8);
                    j.Jogador.Nome = dbReader.GetValue<string>(9);
                    j.Jogador.TimeEscolhido = dbReader.GetValue<string>(10);

                    jogadores.Add(j);
                }
            }

            return jogadores;
        }
    }
}
